<?php

/**
 * 锁机制 类库
 * @copyright Copyright&copy; 2015, 广州六象元一网络科技有限公司
 * @author 王海龙 $
 * @version  $Id: classLock.php, v 1.0, 2015-01-01 王海龙 $
 * 订单生成/修改/删除等基本操作：
*/

class classLock {
    public $mem; // memcached
    private $timeOut = 30; // 锁的有效期限/秒
    private $usleep = 10000; // 循环回调执行间隔/微秒
    private $config = array('512145b6f8ea49a5.m.cnqdalicm9pub001.ocs.aliyuncs.com', 11211, '512145b6f8ea49a5', 'Eggms520');

    /**
     * 构造函数
     */
    public function __construct($config = array()) {
        if (empty($config)) {
            $config = $this->config;
        }
        $this->connect($config);
    }

    /**
     * memcached连接
     *
     * @access  private
     * @param   array   配置数组
     * @return  boolean
     */
    private function connect($config = array()) {
        $this->mem = new memcached();
        // 以二进制进行传输，当要进行密码验证时，这个一定要为true
        $this->mem->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
        // 添加服务池
        $this->mem->addServer($config[0], $config[1]);
        // 进行密码验证
        $this->mem->setSaslAuthData($config[2], $config[3]);
        // 取消自动压缩，如果要后面追加数据，不可压缩数据
        $this->mem->setOption(Memcached::OPT_COMPRESSION, false);
    }

    /**
     * 添加锁
     * @access  public
     * @param   $name  string  锁的名称
     * @param   $timeOut int   监听锁超时时间/秒
     * @return  bool  返回是否成功
     */
    public function lock($name = false, $timeOut = 10000000){
        if (!empty($name)) {
            $usleep = 0; // 监听时长
            while ($usleep < $timeOut){
                if ($this->mem->add($name, 1, $this->timeOut)) {
                    return true;
                    break;
                } else {
                    usleep($this->usleep);
                    $usleep += $this->usleep;
                }
            }
        }
        return false;
    }

    /**
     * 解锁
     */
    public function unlock($name = false){
        if (!empty($name)) {
            $count = 0; // 执行解锁次数
            while ($count < 100){
                if ($this->mem->delete($name)) {
                    return true;
                    break;
                } else {
                    $count ++;
                }
            }
        }
        return false;
    }

}